<template>
  <div
    v-loading="treeLoading"
    :class="[
      'h-full',
      'bg-bg_color',
      'overflow-auto',
      'mr-2',
      deviceDetection() ? 'w-full' : 'min-w-[250px]'
    ]"
    :style="{ minHeight: `calc(100vh - 141px)`, padding: '5px' }"
  >
    <div class="flex items-center h-[34px]">
      <el-input v-model="filterText" placeholder="输入关键字">
        <template #suffix>
          <el-icon class="el-input__icon">
            <IconifyIconOffline
              v-show="filterText.length === 0"
              icon="ri:search-line"
            />
          </el-icon>
        </template>
      </el-input>
      <el-dropdown :hide-on-click="false">
        <IconifyIconOffline
          class="w-[28px] cursor-pointer"
          width="18px"
          :icon="More2Fill"
        />
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item>
              <el-button
                :class="buttonClass"
                link
                type="primary"
                :icon="useRenderIcon(isExpand ? ExpandIcon : UnExpandIcon)"
                @click="toggleRowExpansionAll(isExpand ? false : true)"
              >
                {{ isExpand ? "折叠全部" : "展开全部" }}
              </el-button>
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
    <el-tree
      ref="treeRef"
      class="filter-tree"
      :data="treeData"
      :props="defaultProps"
      default-expand-all
      :filter-node-method="filterNode"
      @node-click="nodeClick"
    />
  </div>
</template>
<script lang="ts" setup>
import { computed, getCurrentInstance, ref, watch } from "vue";
import { ElTree } from "element-plus";
import { deviceDetection } from "@pureadmin/utils";
import More2Fill from "@iconify-icons/ri/more-2-fill";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";

import ExpandIcon from "@/views/system/user/svg/expand.svg?component";
import UnExpandIcon from "@/views/system/user/svg/unexpand.svg?component";

interface Tree {
  [key: string]: any;
}

defineProps({
  treeLoading: Boolean,
  treeData: Array
});

const emit = defineEmits(["tree-select"]);

const filterText = ref("");
const treeRef = ref<InstanceType<typeof ElTree>>();
const isExpand = ref(true);
const highlightMap = ref({});
const { proxy } = getCurrentInstance();

function toggleRowExpansionAll(status) {
  isExpand.value = status;
  const nodes = (proxy.$refs["treeRef"] as any).store._getAllNodes();
  for (let i = 0; i < nodes.length; i++) {
    nodes[i].expanded = status;
  }
}

const defaultProps = {
  children: "children",
  label: "label"
};

const buttonClass = computed(() => {
  return [
    "!h-[20px]",
    "!text-sm",
    "reset-margin",
    "!text-[var(--el-text-color-regular)]",
    "dark:!text-white",
    "dark:hover:!text-primary"
  ];
});

watch(filterText, val => {
  treeRef.value!.filter(val);
});

const filterNode = (value: string, data: Tree) => {
  if (!value) return true;
  return data.label.includes(value);
};

function nodeClick(value) {
  const nodeId = value.$treeNodeId;
  highlightMap.value[nodeId] = highlightMap.value[nodeId]?.highlight
    ? Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
        highlight: false
      })
    : Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
        highlight: true
      });
  Object.values(highlightMap.value).forEach((v: Tree) => {
    if (v.id !== nodeId) {
      v.highlight = false;
    }
  });
  if (!value.children) {
    emit(
      "tree-select",
      highlightMap.value[nodeId]?.highlight
        ? Object.assign({ ...value, selected: true })
        : Object.assign({ ...value, selected: false })
    );
  }
}

function onTreeReset() {
  highlightMap.value = {};
  filterText.value = "";
  toggleRowExpansionAll(true);
}

function setCurrentKey(label: string, status?: boolean) {
  treeRef.value!.setCurrentKey(label, status);
}

defineExpose({
  onTreeReset,
  setCurrentKey
});
</script>

<style scoped lang="scss">
:deep(.el-vl__wrapper > div:first-child) {
  height: calc(100vh - 141px) !important;
}

:deep(.el-vl__wrapper > div:first-child > div:first-child) {
  height: calc(100vh - 141px) !important;
}

.prefix {
  margin-right: 10px;
  color: var(--el-color-primary);
}

.prefix.is-leaf {
  color: var(--el-color-success);
}
</style>
